package com.chepaandvasia.dao;

import com.chepaandvasia.entities.Car;
import com.chepaandvasia.entities.Customer;
import com.chepaandvasia.entities.ServiceCheck;
import com.chepaandvasia.entities.Status;
import java.util.Collections;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Repository(value = "carDAO")
public class CarDAOImpl implements CarDAO {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public void create(Car car) {
		System.out.println(">>>>>>" + entityManager);
		if (car == null || car.getId() != 0) {
			throw new IllegalArgumentException("Illegal car in create method");
		} else {
			entityManager.persist(car);
		}
	}

	@Override
	public Car get(Long id) {
		if (id == null || id < 0) {
			throw new IllegalArgumentException("Illegal id in get method");
		}
		Car car = entityManager.find(Car.class, id);
		return car;
	}

	@Override
	public void update(Car car) {
		if (car == null || car.getId() == 0 || car.getId() < 0) {
			throw new IllegalArgumentException("Illegal car in update method");
		}

		boolean hasActive = false;
		for (ServiceCheck serviceCheck : car.getControlServiceCheck()) {
			if ((!serviceCheck.isCheckDone())
					&& (serviceCheck.getLastCheck() + serviceCheck
							.getCheckInterval()) < car.getNumberOfKms()) {
				serviceCheck.setActive(true);
				hasActive = true;
			}
		}
		if (hasActive) {
			car.setStatus(Status.MAINTENANCE_REQUIRED);
		}
		entityManager.merge(car);
	}

	@Override
	public void remove(Car car) {
		if (car == null || car.getId() == 0 || car.getId() < 0) {
			throw new IllegalArgumentException();
		}
		Car v = entityManager.find(Car.class, car.getId());
		entityManager.remove(v);
	}

	@Override
	public List<ServiceCheck> getActiveServiceChecks(Car car, boolean active) {
		if (car == null || car.getId() == 0) {
			throw new IllegalArgumentException(
					"Illedal car in getActiveServiceChecks method");
		}

		TypedQuery<ServiceCheck> query = entityManager.createQuery(
				"SELECT s FROM Car c,IN(c.controlServiceCheck) s"
						+ "WHERE v = :car AND s.isActive = :active",
				ServiceCheck.class);
		query.setParameter("active", active);
		query.setParameter("car", car);
		List<ServiceCheck> serviceList = query.getResultList();
		return Collections.unmodifiableList(serviceList);
	}

	@Override
	public List<Car> findAllCarsForCustomer(Customer customer) {
		TypedQuery<Car> query = entityManager.createQuery(
				"SELECT c FROM Car c WHERE c.status = :status", Car.class);
		query.setParameter("status", Status.AVAILABLE);
		List<Car> carList = query.getResultList();
		return Collections.unmodifiableList(carList);
	}

	@Override
	public List<Car> findAllCars() {
		TypedQuery<Car> query = entityManager.createQuery(
				"SELECT c FROM Car c", Car.class);
		List<Car> carList = query.getResultList();
		return Collections.unmodifiableList(carList);
	}

	@Override
	public List<Car> getCarsByStatus(Status status) {
		TypedQuery<Car> query = (TypedQuery<Car>) entityManager.createQuery(
				"SELECT c FROM Car c WHERE c.status = :status", Car.class);
		query.setParameter("status", status);
		List<Car> carList = query.getResultList();
		return Collections.unmodifiableList(carList);
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
}